# 公共方法文件
import asyncio
import io
import math
from typing import List

import pandas as pd

from common.model import BaseData, CompletionData
from common.client import client, putObject



# 计算全角
def get_full_angle(a: BaseData, b: BaseData) -> float:
    # 定义计算元
    factor_a: float = math.cos(math.radians(b.inclination)) * math.cos(math.radians(a.inclination))
    factor_b: float = math.sin(math.radians(b.inclination)) * math.sin(math.radians(a.inclination)) * math.cos(
        math.radians(get_delta_azimuth(a, b))
    )
    t: float = factor_a + factor_b
    # @TODO 全角计算此处需要修正吗?
    if t >= 1.0:
        t = 0.9999999999
    factor_res: float = math.acos(t)
    return math.degrees(factor_res)


# 偏移量计算系数
def get_delta_factor(a: BaseData, b: BaseData) -> float:
    # 全角计算
    full_angle: float = get_full_angle(a, b)
    # 如果全角 = 0
    if full_angle.__eq__(0.0):
        return get_delta_depth(a, b) * 0.5
    else:
        # 180/PI
        return ((180 * math.pow(math.pi, -1))
                * (get_delta_depth(a, b) * math.pow(full_angle, -1))
                * math.tan(math.radians(full_angle * 0.5)))


# 获取深度变化 delta_depth
def get_delta_depth(a: BaseData, b: BaseData) -> float:
    return a.depth - b.depth


# 计算方位角增量
def get_delta_azimuth(a: BaseData, b: BaseData) -> float:
    return a.azimuth - b.azimuth


# 获取曲率半径 依赖于全角计算
def get_curvature_radius(a: CompletionData, b: CompletionData) -> float:
    # print(JsonUtil.obj2str(a))
    # print(JsonUtil.obj2str(b))
    # print(get_full_angle(a,b))
    # 需要将全角转化为弧度
    return get_delta_depth(a, b) * math.pow(math.radians(get_full_angle(a, b)), -1)


# 通用存储接口
def save(bucketName: str, objectName: str, _list_):
    data = []
    for obj in _list_:
        data.append(vars(obj))
    df = pd.DataFrame(data)
    # 生成并上传Excel数据
    excel_data = df
    # 将数据写入Excel文件
    excel_file = io.BytesIO()
    excel_data.to_excel(excel_file, index=False)
    excel_file.seek(0)
    putObject(bucketName, objectName, excel_file)


# 读取数据
# def read(bucketName: str, objectName: str):
#     file_data = client.get_object(bucketName, objectName)
#     df = pd.read_excel(io.BytesIO(file_data.read()))
#     data_list: List[BaseData] = []
#     data_list = [SampleObject(**item) for item in json.loads(object_data.decode('utf-8'))]
#     for index, row in df.iterrows():
#         item: BaseData = BaseData()
#         item.depth = row['depth']
#         item.inclination = row['inclination']
#         item.azimuth = row['azimuth']
#         data_list.append(item)
#     return data_list



def get_instrument_area(params) -> float:
    return math.pi * 0.25 * math.pow(params.d1, 2)


# 测井仪器的单位密度
def get_instrument_uint_density(params) -> float:
    return params.m1 / get_instrument_area(params)


# 测井仪器的单位浮重
def get_instrument_unit_weight(params) -> float:
    return (get_instrument_uint_density(params) - params.rou_m) * get_instrument_area(params) * 9.81


# 电缆截面面积
def get_cable_area(params) -> float:
    return math.pi * 0.25 * math.pow(params.d2, 2)


# 电缆的单位密度
def get_cable_uint_density(params) -> float:
    return params.m2 / get_cable_area(params)


# 电缆的单位浮重
def get_cable_unit_weight(params) -> float:
    return (get_cable_uint_density(params) - params.rou_m) * get_cable_area(params) * 9.81


# 电缆的界面惯性矩
def get_cable_moment_inertia(params) -> float:
    return math.pi * math.pow(params.d2, 4) / 64


# 原始电缆的弹性模量
def get_cable_elastic_modulus(params) -> float:
    return (5000 * 1000) / (params.cable_stretch * get_cable_area(params))


# 修正系数
def get_correction_factor(params) -> float:
    k: float = 0.75 + 0.0001  * params.rou_m
    return k


# 修正的电缆弹性模量
def get_corrected_cable_elastic_modulus(params) -> float:
    return get_correction_factor(params) * get_cable_elastic_modulus(params)


# 马氏漏斗粘度转换
def get_conversion_viscosity(params) -> float:
    factor_a: float = math.pow(10, -3)
    factor_b: float = math.log((params.tao_s-24.5)/0.58)/1.2
    factor_c: float = math.log(params.rou_m * factor_a)
    viscosity: float = factor_a * math.pow(math.e, factor_b + factor_c)
    return viscosity

